﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FinalPointSet.Model.Constant;
using FinalPointSet.Model.Constant.Message;
using FinalPointSet.Model.Constants;
using FinalPointSet.Model.Manager;
using FinalPointSet.Model.Util;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using static FinalPointSet.Model.Manager.MessageManager;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;

namespace FinalPointSet.ViewModel.Page.MainView
{
    public partial class SettingPageViewModel : ObservableObject
    {
        /// <summary>
        /// 搜索页面快捷键的状态
        /// </summary>
        [ObservableProperty]
        private ButtonStyle? _SearchViewHotKeyStateLogoStyle = ButtonStyle.Success;
        /// <summary>
        /// 主页面快捷键的状态
        /// </summary>
        [ObservableProperty]
        private ButtonStyle? _MainViewHotKeyStateLogoStyle = ButtonStyle.Success;
        /// <summary>
        /// 搜索页面快捷键的可见状态
        /// </summary>
        [ObservableProperty]
        private Visibility _SearchViewHotKeyStateLogoVisibility = Visibility.Hidden;
        /// <summary>
        /// 主页面快捷键的可见状态
        /// </summary>
        [ObservableProperty]
        private Visibility _MainViewHotKeyStateLogoVisibility = Visibility.Hidden;
        /// <summary>
        /// 搜索页面快捷键清除按钮的可见状态
        /// </summary>
        [ObservableProperty]
        private Visibility _SearchViewHotKeyClearButtonVisibility = Visibility.Hidden;
        /// <summary>
        /// 主页面快捷键清除按钮的可见状态
        /// </summary>
        [ObservableProperty]
        private Visibility _MainViewHotKeyClearButtonVisibility = Visibility.Hidden;
        /// <summary>
        /// 是否开机启动
        /// </summary>
        [ObservableProperty]
        private bool _IsPowerBoot = Settings.Default.IsPowerBoot;
        /// <summary>
        /// 搜索页面的快捷键文本
        /// </summary>
        [ObservableProperty]
        private string _SearchViewHotKeyText = string.Empty;
        /// <summary>
        /// 主页面的快捷键文本
        /// </summary>
        [ObservableProperty]
        private string _MainViewHotKeyText = string.Empty;

        private readonly List<HotKeyCombination> HotKeyCombinations = HotKeyManager.Instance.HoyKeyCombinations;

        public SettingPageViewModel() { }
        [RelayCommand]
        private void PowerBootChecked()
        {
            Debug.Print("SettingPageViewModel.PowerBootChecked()");
            SetPowerBoot(true);
            Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, $"设置开机启动成功!"));
        }
        [RelayCommand]
        private void PowerBootUnchecked()
        {
            Debug.Print("SettingPageViewModel.PowerBootUnchecked()");
            SetPowerBoot(false);
            Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, $"取消开机启动成功!"));
        }
        [RelayCommand]
        private void Reset(string param)
        {
            Debug.Print($"SettingPageViewModel.Reset(), param={param}");
            //取消注册快捷键
            HotKeyManager.Instance.UnRegistHotKey(param);
            //判断当前快捷键类型
            if (HotKeyManager.SearchView.Equals(param))
            {
                SearchViewHotKeyText = string.Empty;
            }
            else if (HotKeyManager.MainView.Equals(param))
            {
                MainViewHotKeyText = string.Empty;
            }

            //隐藏按钮显示
            SetHotKeyClearButtonVisibility(param, Visibility.Collapsed);
            SetHotKeyRegistStateLogoVisibility(param, Visibility.Collapsed);
            //重置变量
            ResetHotKeyVar();
            ResetHotKeyCombination(param);
            //保存配置
            HotKeyManager.Instance.Save();
        }

        /// <summary>
        /// 更新搜索框的UI
        /// </summary>
        /// <param name="param"></param>
        [RelayCommand]
        private void TextChange(string param)
        {
            Debug.Print($"SettingPageViewModel.TextChange(), param={param}");
            SetHotKeyLogoState(param);
        }

        /// <summary>
        /// 最多输入的特殊按键的数量
        /// </summary>
        private const int MaxInputKey = 3;
        private int inputKeyCnt = 0;
        private Key normalKey = Key.None;
        private readonly List<Key> specialKeys = new();
        public void HotKeySettingInput(KeyEventArgs e, string keyName)
        {
            Key inputKey = e.Key;
            Debug.Print($"SettingPageViewModel.HotKeySettingInput(), 当前输入={inputKey}");
            //判断按键输入数量
            if (inputKeyCnt > MaxInputKey)
            {
                Debug.Print($"SettingPageViewModel.HotKeySettingInput(), 当前输入的特殊按键已超过{MaxInputKey}个");
                return;
            }

            //判断输入是否合规
            if (!HotKeyUtil.CanBeSetting(inputKey) || normalKey == inputKey || specialKeys.Contains(inputKey))
            {
                Debug.Print($"SettingPageViewModel.HotKeySettingInput(), 当前输入的按键不符合设定");
                return;
            }
            //Debug.Print($"SettingPageViewModel.HotKeySettingInput(), hotKeySettingType={keyName}, key={inputKey}");
            HotKeyCombination hotKeyCombination = HotKeyCombinations.First(k => k.Name.Equals(keyName));
            //特殊键
            if (HotKeyUtil.IsSpecialKey(inputKey) && inputKeyCnt < MaxInputKey)
            {
                specialKeys.Add(inputKey);
                inputKeyCnt++;
            }
            //普通键
            else
            {
                if (normalKey != Key.None) return;
                normalKey = inputKey;
                //完成输入的标准 = 输入了普通按键
                Debug.Print($"SettingPageViewModel.HotKeySettingInput(), KeyName={keyName}, 当前键值情况: normalKey={normalKey}, specialKeys={string.Join(',', specialKeys)}, inputKeyCnt={inputKeyCnt}");
                Debug.Print($"SettingPageViewModel.HotKeySettingInput(), 设置快捷键输入完毕");
                //更新快捷键组合数据
                hotKeyCombination.NormalKey = HotKeyUtil.GetHotKey(normalKey);
                hotKeyCombination.SpecialKeys = HotKeyUtil.GetHotKeys(specialKeys);
                hotKeyCombination.Count = specialKeys.Count + 1;
                //检测设置的快捷键是否合规
                CheckHotKeyInput(hotKeyCombination);
            }

        }

        /// <summary>
        /// 检测快捷键的输入合规, 没有问题则进行注册
        /// </summary>
        /// <param name="hotKeyCombination"></param>
        private void CheckHotKeyInput(HotKeyCombination hotKeyCombination)
        {
            string keyName = hotKeyCombination.Name;
            Key normalKey = hotKeyCombination.NormalKey.Key;
            List<Key> specialKeys = hotKeyCombination.SpecialKeys.Select(k => k.Key).ToList();
            //更新UI显示
            SetHotKeyTextBoxText(keyName, normalKey, specialKeys);

            if (normalKey == Key.None)
            {
                hotKeyCombination.RegistResult = RegistResult.None;
            }
            else if (specialKeys.Count == 0)
            {
                hotKeyCombination.RegistResult = RegistResult.Warn;
            }
            else
            {
                //判断快捷键注册状态
                bool isSuccess = CheckHotKeyRegistState(keyName);
                if (isSuccess)
                {
                    hotKeyCombination.RegistResult = RegistResult.Success;
                }
                else
                {
                    hotKeyCombination.RegistResult = RegistResult.Error;
                }
                HotKeyManager.Instance.Save();
            }

            //显示logo
            SetHotKeyLogoState(keyName);
            if (hotKeyCombination.RegistResult != RegistResult.None)
            {
                SetHotKeyRegistStateLogoVisibility(keyName, Visibility.Visible);
                SetHotKeyClearButtonVisibility(keyName, Visibility.Visible);
            }
            else
            {
                SetHotKeyRegistStateLogoVisibility(keyName, Visibility.Collapsed);
                SetHotKeyClearButtonVisibility(keyName, Visibility.Collapsed);
            }
        }

        /// <summary>
        /// 重置热键变量
        /// </summary>
        private void ResetHotKeyVar()
        {
            //清空缓存变量
            inputKeyCnt = 0;
            normalKey = Key.None;
            specialKeys.Clear();
        }

        /// <summary>
        /// 重置热键变量
        /// </summary>
        private void ResetHotKeyCombination(string keyName)
        {
            HotKeyCombination hotKeyCombination = HotKeyCombinations.First(k => k.Name == keyName);
            hotKeyCombination.NormalKey = HotKeyMapping.Keys[Key.None];
            hotKeyCombination.SpecialKeys.Clear();
            hotKeyCombination.Count = 0;
        }

        /// <summary>
        /// 松开按键
        /// </summary>
        /// <param name="e"></param>
        /// <param name="hotKeySettingType"></param>
        public void HotKeySettingEndInput(KeyEventArgs e, string hotKeySettingType)
        {
            Debug.Print($"SettingPageViewModel.HotKeySettingEndInput(), hotKeySettingType={hotKeySettingType}, key={e.Key}");
            //松开按键, 清空缓存的变量     
            ResetHotKeyVar();
        }

        /// <summary>
        /// 更新快捷键文本框的显示
        /// </summary>
        /// <param name="hotKeySettingType">快捷键类型</param>
        /// <param name="text">文本</param>
        private void SetHotKeyTextBoxText(string hotKeySettingType, Key normalKey, List<Key> specialKeys)
        {
            string hotkeyText = HotKeyUtil.GetHotKeyCombinationName(normalKey, specialKeys);
            switch (hotKeySettingType)
            {
                case HotKeyManager.SearchView:
                    SearchViewHotKeyText = hotkeyText;
                    break;
                case HotKeyManager.MainView:
                    MainViewHotKeyText = hotkeyText;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 更新快捷键注册状态Logo的UI
        /// </summary>
        /// <param name="hotKeySettingType"></param>
        /// <param name="style"></param>
        private void SetHotKeyRegistStateStyle(string hotKeySettingType, ButtonStyle style)
        {

            switch (hotKeySettingType)
            {
                case HotKeyManager.SearchView:
                    SearchViewHotKeyStateLogoStyle = style;
                    break;
                case HotKeyManager.MainView:
                    MainViewHotKeyStateLogoStyle = style;
                    break;
                default:
                    break;
            }
        }

        private void SetHotKeyRegistStateLogoVisibility(string hotKeySettingType, Visibility visibility)
        {
            switch (hotKeySettingType)
            {
                case HotKeyManager.SearchView:
                    SearchViewHotKeyStateLogoVisibility = visibility;
                    break;
                case HotKeyManager.MainView:
                    MainViewHotKeyStateLogoVisibility = visibility;
                    break;
                default:
                    break;
            }
        }

        private void SetHotKeyClearButtonVisibility(string hotKeySettingType, Visibility visibility)
        {
            switch (hotKeySettingType)
            {
                case HotKeyManager.SearchView:
                    SearchViewHotKeyClearButtonVisibility = visibility;
                    break;
                case HotKeyManager.MainView:
                    MainViewHotKeyClearButtonVisibility = visibility;
                    break;
                default:
                    break;
            }
        }

        private void SetHotKeyLogoState(string param)
        {
            //判断当前快捷键类型, 根据是否有输入快捷键设置调整可见状态
            HotKeyCombination hotKeyCombination = HotKeyCombinations.First(k => k.Name.Equals(param));
            //更新可见度
            if (!string.IsNullOrEmpty(SearchViewHotKeyText) || !string.IsNullOrEmpty(MainViewHotKeyText))
            {
                SetHotKeyRegistStateLogoVisibility(param, Visibility.Visible);
                SetHotKeyClearButtonVisibility(param, Visibility.Visible);
            }
            else
            {
                SetHotKeyRegistStateLogoVisibility(param, Visibility.Collapsed);
                SetHotKeyClearButtonVisibility(param, Visibility.Collapsed);
            }

            //更新按钮的状态
            if (hotKeyCombination.RegistResult == RegistResult.Success)
            {
                SetHotKeyRegistStateStyle(param, ButtonStyle.Success);
            }
            else if (hotKeyCombination.RegistResult == RegistResult.Warn)
            {
                SetHotKeyRegistStateStyle(param, ButtonStyle.Warn);
            }
            else if (hotKeyCombination.RegistResult == RegistResult.Error)
            {
                SetHotKeyRegistStateStyle(param, ButtonStyle.Error);
            }
        }

        /// <summary>
        /// 判断快捷键注册是否成功
        /// </summary>
        /// <param name="keyName"></param>
        /// <returns></returns>
        private static bool CheckHotKeyRegistState(string keyName)
        {
            //先取消注册，再进行新的注册
            HotKeyManager.Instance.UnRegistHotKey(keyName);
            return HotKeyManager.Instance.RegistHotkey(keyName);
        }

        /// <summary>
        /// 更新UI显示
        /// </summary>
        public void InitHotKeyState()
        {
            //更新UI显示
            foreach (var item in HotKeyCombinations)
            {
                CheckHotKeyInput(item);
            }
        }
        /// <summary>
        /// 设置开机启动
        /// </summary>
        /// <param name="isPowerBoot"></param>
        private void SetPowerBoot(bool isPowerBoot)
        {
            bool result = PowerBootUtil.SetPowerBoot(isPowerBoot);
            //设置开启自启但是失败
            if (isPowerBoot && !result)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, "开机启动设置失败，请尝试使用管理员权限开启程序!"));
                return;
            }
            else if (!isPowerBoot && !result)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, "关闭开机启动失败, 请尝试使用管理员权限开启程序!"));
                return;
            }

            Settings.Default.IsPowerBoot = IsPowerBoot;
            Settings.Default.Save();
        }
    }

    /// <summary>
    /// 快捷键实体类
    /// </summary>
    public class HotKeyValue
    {
        public HotKeyValue() { }
        public HotKeyValue(string settingType, bool isSetting, Key normalKey, List<Key> specialKeys)
        {
            SettingType = settingType;
            IsSetting = isSetting;
            NormalKey = normalKey;
            SpecialKeys = specialKeys;
        }

        /// <summary>
        /// 快捷键类型
        /// </summary>
        public string SettingType { get; set; } = string.Empty;
        /// <summary>
        /// 当前是否正在设置快捷键中
        /// </summary>
        public bool IsSetting { get; set; } = false;
        /// <summary>
        /// 普通键
        /// </summary>
        public Key NormalKey { get; set; } = Key.None;
        /// <summary>
        /// 特殊键
        /// </summary>
        public List<Key> SpecialKeys { get; set; } = new();
        /// <summary>
        /// 设置快捷键的按键数量
        /// </summary>
        public int Count { get; set; } = 0;

    }
    /// <summary>
    /// 按钮的样式
    /// </summary>
    public class ButtonStyle
    {
        /// <summary>
        /// 正确样式
        /// </summary>
        public static ButtonStyle Success = new("#33b638", "\ue632", "设置成功");
        /// <summary>
        /// 错误样式
        /// </summary>
        public static ButtonStyle Error = new("#ff645c", "\ue8e7", "快捷键注册失败");
        /// <summary>
        /// 警告样式
        /// </summary>
        public static ButtonStyle Warn = new("#fecb1e", "\ue611", "快捷键过于简单, 影响正常使用, 请重新设置!");
        public string Background { get; set; } = "#afb5c2";
        public string Logo { get; set; } = string.Empty;
        public string ToolTip { get; set; } = string.Empty;
        public ButtonStyle() { }
        public ButtonStyle(string background, string logo, string tooltip)
        {
            Background = background;
            Logo = logo;
            ToolTip = tooltip;
        }
    }
}
